package com.alks.function.service.impl.procurement;


import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.dto.SysUserTokenDTO;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.common.utils.DateUtils;
import com.alks.common.utils.beanutils.ObjectUtils;
import com.alks.common.utils.excelUtils.CellStyleBuild;
import com.alks.common.utils.excelUtils.ExcelPoiUtils;
import com.alks.common.utils.excelUtils.ExcelUtils;
import com.alks.common.utils.excelUtils.MergeBuild;
import com.alks.entity.data.entity.PcPackOther;
import com.alks.entity.data.entity.PurCompany;
import com.alks.entity.data.entity.SdCompany;
import com.alks.entity.data.entity.SdVendor;
import com.alks.entity.data.enums.CompanyEnum;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.dto.administration.PcEmployeeListDto;
import com.alks.function.data.dto.procurement.PcPackDetailDto;
import com.alks.function.data.dto.procurement.PcPackOtherDto;
import com.alks.function.data.request.administration.PcEmployeeRequest2;
import com.alks.function.data.request.procurement.*;
import com.alks.function.mapper.SdCompanyMapper;
import com.alks.function.mapper.administration.PcEmployeeMapper;
import com.alks.function.mapper.common.BackMapper;
import com.alks.function.mapper.procurement.PackagOtherOrderingOperationMapper;
import com.alks.function.mapper.procurement.PurCompanyMapper;
import com.alks.function.mapper.stockdept.pcfactorystockquery.SD_SQ_PcPackDetailMapper;
import com.alks.function.service.procurement.PackagOtherOrderingOperationService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.support.atomic.RedisAtomicInteger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static cn.hutool.core.date.DateTime.now;
import static com.alks.entity.data.enums.ResultCodeEnum.IN_IS_EMPTY;

@Service
@Slf4j
public class PackagOtherOrderingOperationServiceImpl implements PackagOtherOrderingOperationService {

    @Autowired
    private PackagOtherOrderingOperationMapper pOtherOrderingOperationMapper;

    @Autowired
    private SD_SQ_PcPackDetailMapper lotMtlMapper;

    @Autowired
    private BackMapper backMapper;

    @Autowired
    private  RedisService redisService;

    @Autowired
    private PurCompanyMapper purMapper;

    @Autowired
    private PcEmployeeMapper pcEmployeeMapper;

    /**
     * 待订购明细-查询
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getNotOrderMaterialList(NotOrderMaterialRequest request) {
        //史倩待完成 查询条件少了
        String companyId = UserIdThread.get().getCompanyId();
        //分页:查询前用pagehelper.startPage方法进行分页
        if (request.getPageNum() == null || request.getPageSize() == null) {
            // 处理页码或页面大小为空的情况，这里可以选择抛出异常或者返回错误信息
            throw new ServiceErrorException("分页参数异常");
        }

        List<PcPackOtherDto> notOrderMaterialList = pOtherOrderingOperationMapper.getNotOrderMaterialList(companyId,request);
//        notOrderMaterialList.stream().forEach(dto -> dto.setPurQty(dto.getTtlUsage()));

        PageInfo list = new PageInfo(notOrderMaterialList);
        HashMap map = new HashMap<>();
        map.put("lotNoList", notOrderMaterialList);
        map.put("total", list.getTotal());
        return ResponseInfo.ok(map);
    }

    /**
     * 已订购明细-查询
     * @param request
     * @return
     */
    @Override
    @AutoPageAop
    public ResponseInfo getOrderedDetailsList(NotOrderMaterialRequest request) {
        //史倩待完成 查询条件少了
        String companyId = UserIdThread.get().getCompanyId();
        //分页:查询前用pagehelper.startPage方法进行分页
        if (request.getPageNum() == null || request.getPageSize() == null) {
            // 处理页码或页面大小为空的情况，这里可以选择抛出异常或者返回错误信息
            throw new ServiceErrorException("分页参数异常");
        }
        List<PcPackOtherDto> notOrderMaterialList = pOtherOrderingOperationMapper.getOrderedDetailsList(companyId,request);

        PageInfo list = new PageInfo(notOrderMaterialList);
        HashMap map = new HashMap<>();
        map.put("lotNoList", notOrderMaterialList);
        map.put("total", list.getTotal());
        return ResponseInfo.ok(map);
    }

    /**
     * 已订购明细-批量更新（备注+请购类型）
     * @param request
     * @return
     */
    @Override
    public ResponseInfo updateOrderedRemark(List<PcPackDetailRequest> request) {
        //只备注+请购类型
        int count = pOtherOrderingOperationMapper.updateBatchOrderedDetails(request);
        if(count > 0){
            return ResponseInfo.ok("修改成功");
        }else{
            throw new ServiceErrorException("修改失败");
        }
    }

    /**
     * 修改需求日期/单价
     * @param r
     * @return
     */
    @Override
    public ResponseInfo updateReqDateAndUPrice(NewPcPackDetailRequest r) {
        String companyId = UserIdThread.get().getCompanyId();
        PcPackDetailRequest request = r.getRequest();
        int count = pOtherOrderingOperationMapper.updateReqDateAndUPrice(companyId,request,r.getNewPrice(),r.getNewPurDate());
        if(count > 0){
            return ResponseInfo.ok("修改成功");
        }else{
            throw new ServiceErrorException("修改失败");
        }
    }

    /**
     * 待订购明细:编辑
     * @param request
     * @return
     */
    @Override
    public ResponseInfo updateBatchNotOrderMaterial(List<PcPackDetailRequest> request) {
        //清购类型，指令，型体，订购数量，订购单价
        //史倩待完成 判断指令
        int count = pOtherOrderingOperationMapper.updateBatchNotOrderDetails(request);
        if(count > 0){
            return ResponseInfo.ok("修改成功");
        }else{
            throw new ServiceErrorException("修改失败");
        }
    }

    /**
     * 勾选待订购
     * @param r
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo getBatchProcess(BatchProcessNotOrderMaterialRequest r) {
        List<PcPackDetailRequest> request = r.getRequest();
        /*判空*/
        if (request == null || request.isEmpty()) {
            throw new ServiceErrorException("请选择订购指令材料");
        }
        //订购数量不能未0
        boolean result = request.stream()
                .anyMatch(dto -> BigDecimal.ZERO.equals(dto.getPrice()) || Objects.isNull(dto.getPrice()));
        if(result){
            throw new ServiceErrorException("订购数量不能为0！");
        }
        if(r.getDate() == null || r.getVendorName() == null){
            throw new ServiceErrorException("请选择厂商、交期、币别！");
        }
        /*获取数据*/
        String companyId = UserIdThread.get().getCompanyId();
        String companyName = backMapper.getVendorNoByName(companyId);

        /*填充数据*/
        request.forEach(dto -> {
            dto.setCompanyId(companyId);
            dto.setVendorNo(r.getVendorNo());
            dto.setPurQty(dto.getPurQty());
            dto.setReqDate(r.getDate());
            dto.setPrice(dto.getPrice());
            dto.setAmt(dto.getPurQty().multiply(dto.getPrice()));
            dto.setCurrency("RMB");
            dto.setPayDays(BigDecimal.valueOf(90));
            dto.setInvoiceType("Y");
            dto.setDeliveryPlace(companyName);
            if (dto.getPurFlag() != null) {
                dto.setPurFlag(dto.getPurFlag().equals("1") ? "Y" : null);
            }
        });
        /*更新*/
        int count = pOtherOrderingOperationMapper.updateBatchOrderedDetails(request);
        if(count > 0){
            return ResponseInfo.ok("待订购完成 " + count + " 条记录！");
        }else{
            throw new ServiceErrorException("订购失败！");
        }
    }

    /**
     * 生成订购单
     * @param r
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo makePurchaseOrder(BatchProcessNotOrderMaterialRequest r) {
        List<PcPackDetailRequest> request = r.getRequest();
        /*判空*/
        if (request == null || request.isEmpty()) {
            throw new ServiceErrorException("请选择订购指令材料");
        }
        if (ObjectUtils.isNull(r.getVendorNo()) && ObjectUtils.isNull(r.getDate())) {
            throw new ServiceErrorException("请选择厂商、交期！");
        }
        List<PcPackDetailRequest> collect = request.stream()
                .filter(o -> o.getPurQty() == null || o.getPrice() == null )
                .collect(Collectors.toList());

        if (!collect.isEmpty()) {
            throw new ServiceErrorException("订购数量和单价不能为空！");
        }
        /*获取数据*/
        String companyId = UserIdThread.get().getCompanyId();
        String companyName = backMapper.getVendorCompanyNameByCompanyId(companyId);

        //2.订购单号生成
        String time = "yyMMddHH";
        String key = "PackagOrderingOperation/makePurchaseOrder" + companyId + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMM"));//自增数字里面加上年月;
        String value = generatePrefix(key, "5", time);
        //公司名字
        PurCompany companyDto = purMapper.findPurCompanyInfo(companyId);
        String companyAddr = companyDto.getShortName();
        String purNo = CompanyEnum.updateId(companyId) + "B" + value;

        //3.可以批量数据
        request.forEach(ord -> {
            ord.setCompanyId(companyId);
            ord.setPurNo(purNo);
            ord.setVendorNo(r.getVendorNo());
            ord.setVendorName(r.getVendorName());
            ord.setPurQty(ord.getPurQty());
            ord.setReqDate(r.getDate());
            ord.setPurDate(now());
            ord.setPrice(ord.getPrice());
            ord.setAmt(ord.getPurQty().multiply(ord.getPrice()));
            ord.setCurrency("RMB");
            ord.setPayDays(BigDecimal.valueOf(90));
            ord.setInvoiceType("Y");
            ord.setDeliveryPlace(companyName);
            ord.setPurType(ord.getPurType());
        });
        //4.批量插入
        int count = pOtherOrderingOperationMapper.makePurchaseOrder(request);
        if(count > 0){
            return ResponseInfo.ok("成功形成订购单，订购单号：" + purNo);
        }else{
            throw new ServiceErrorException("形成订购单失败！");
        }
    }

    /**
     * 订购单取消
     * @return
     */
    @Override
    public ResponseInfo cancelOrderedDetails(String slipNo) {
        int count = pOtherOrderingOperationMapper.updateBatchOrderedBeNull(slipNo);
        if(count > 0){
            return ResponseInfo.ok("取消成功！");
        }else{
            throw new ServiceErrorException("订购单取消失败！");
        }
    }

    /**
     * 双击料号选择材料
     * @param request
     * @return
     */
    @Override
    @Transactional
    public ResponseInfo selectMaterial(List<SdMaterialRequest> request) {
        if (request == null  || request.isEmpty()) {
            throw new ServiceErrorException("请选择指令材料");
        }
        String companyId = UserIdThread.get().getCompanyId();
        String userName = UserIdThread.get().getUserName();
        ArrayList<PcPackOther> others = new ArrayList<>();
        for (SdMaterialRequest materialRequest : request) {
            PcPackOther pcPackOther = new PcPackOther();
            BeanUtils.copyProperties(materialRequest, pcPackOther);
            pcPackOther.setCompanyId(companyId);
            pcPackOther.setSysUser(userName);
            //pcPackOther.setSeqNo(materialRequest.getMtlType());
            pcPackOther.setTypeName(materialRequest.getTypeName());
            others.add(pcPackOther);
        }
        int count = pOtherOrderingOperationMapper.addBatchOrderedMaterial(others);
        if(count > 0){
            return ResponseInfo.ok("选择材料成功！");
        }else{
            throw new ServiceErrorException("选择材料失败！");
        }
    }

    /**
     * 导出订购单
     * @param response
     */
    @Override
    public void exportPurchaseOrder(NotOrderMaterialRequest r, HttpServletResponse response) {

        if(r.getPurNo() == null || r.getPurNo().isEmpty()){
            throw new ServiceErrorException("订购单号不能为空！");
        }

        String fileName = "包材订购单_" +r.getVendorName() + "_" + DateUtils.dateTimeNow() + ".xlsx";
        //request : purNo + vendorName
        HashMap<String, Object> map = new HashMap<>();
        String companyId = UserIdThread.get().getCompanyId();
        String userName = UserIdThread.get().getUserName();

        /*查询*/
        NotOrderMaterialRequest request = new NotOrderMaterialRequest();
        request.setPurNo(r.getPurNo());
        List<PcPackOtherDto> list = pOtherOrderingOperationMapper.getOrderedDetailsList(companyId,request);
        if(ObjectUtils.isNotEmpty(list) && list.size() > 0){
            PcPackOtherDto pcPackOtherDto = list.get(0);
            //厂商名字
            SdVendor vendorDto = backMapper.getVendorNameByNo(list.get(0).getVendorNo(),companyId);
            //公司名字
            PurCompany companyDto = purMapper.findPurCompanyInfo(companyId);
            //电话
            PcEmployeeRequest2 employeeRequest = new PcEmployeeRequest2();
            employeeRequest.setDeptNo(UserIdThread.get().getDeptId());
            employeeRequest.setName(UserIdThread.get().getUserName());
            List<PcEmployeeListDto> pcEmployeeList = pcEmployeeMapper.getPcEmployeeList(employeeRequest);
            String phonenumber = null;
            if(ObjectUtils.isNotEmpty(pcEmployeeList) && pcEmployeeList.size()>0){
                PcEmployeeListDto pcEmployeeDto = pcEmployeeList.get(0);
                phonenumber = pcEmployeeDto.getMobileNo();
            }

//        BigDecimal count = BigDecimal.ZERO;
            int count = 0;
            for (PcPackOtherDto t : list) {
                if (!ObjectUtils.isEmpty(t.getPurQty())) {
                    count = count + t.getPurQty();
                }
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            pcPackOtherDto.setPurDateString(sdf.format(pcPackOtherDto.getPurDate()));
            pcPackOtherDto.setReqDateString(sdf.format(pcPackOtherDto.getReqDate()));

            //如果是越南那边，包材的订购单落款人和电话取purCompany
            if(companyId.equals("HF")){
                phonenumber = companyDto.getTelPhone();
                userName = companyDto.getContacts();
            }

            map.put("mapList", list);
            map.put("p", pcPackOtherDto);
            map.put("v", vendorDto);
            map.put("c", companyDto);
            map.put("count", count);
            map.put("userName", userName);
            map.put("phonenumber", phonenumber);
        }
        try {
            ExcelUtils.setResponseZF(response, fileName);
            ExcelPoiUtils.writeExcelList(response, map, "templates/包材订购单(请购类型)模板.xls", fileName);
        } catch (Exception e) {
            log.error("包材订购单导出失败, 错误信息: {}", e.getMessage());
            throw new ServiceErrorException(e.getMessage());
        }
    }

    /**
     * 导出订购单(分段/纵)
     * @param request
     * @param response
     */
    @Override
    public void exportPurchaseOrderByLongitudinal(NotOrderMaterialRequest request, HttpServletResponse response) {
        try {

            /*判断*/
            if(request.getPurNo() == null || request.getPurNo().isEmpty()){
                throw new ServiceErrorException("订购单号不能为空！");
            }

            /*文件*/
            //文件名称
            String fileName = "订购单(分段/纵)_" + request.getVendorName() + "_" + DateUtils.dateTimeNow() + ".xlsx";
            //request : purType + purNo + vendorName
            HashMap<String, Object> map = new HashMap<>();
            //中间表格数据
            List<List<String>> dateList = new ArrayList<>();

            /*查询所有的数据*/
            //查询该单号的所有数据
            SysUserTokenDTO sysUserTokenDTO = UserIdThread.get();
            String companyId = sysUserTokenDTO.getCompanyId();
            NotOrderMaterialRequest r = new NotOrderMaterialRequest();
            r.setPurNo(request.getPurNo());
            String purNo = request.getPurNo();
            List<PcPackOtherDto> allDateList = pOtherOrderingOperationMapper.getOrderedDetailsList(companyId,r);
            //查询：统计LotNo() + MtlName() + getMtlUnit() + Size1() + Size2()相同的数据的订购数量(按照指令升序，物料编码升序)
            List<PcPackOtherDto> sameConditionList = pOtherOrderingOperationMapper.getOrdersByCondition(companyId,purNo);
            //查询：分组查询该指令的MtlName() + getMtlUnit() + Size1() + Size2()相同的数据(按照物料编码升序)
            List<PcPackOtherDto> sameConditionList2 = pOtherOrderingOperationMapper.getOrdersByCondition2(companyId,purNo);
            //list判空
            if(ObjectUtils.isEmpty(allDateList) || ObjectUtils.isEmpty(sameConditionList) || ObjectUtils.isEmpty(sameConditionList2)){
                throw new ServiceErrorException("未找到该订单号材料");
            }

            /*1.数据处理：处理中间表格数据*/
            //a.处理表头变化的指令数据
            // 如果确实需要List<String>类型的lotNoList，可以在转换前先收集到List，再转换为单个字符串
            List<String> headlotNoList = allDateList.stream()
                    .map(dto -> dto.getLotNo().substring(dto.getLotNo().indexOf("-") + 1))
                    .distinct()
                    .sorted() //升序排序
                    .collect(Collectors.toList());
            //b.处理第二列指令单号列数据
            // 整合操作，提取、处理、去重并用换行符连接
            String lotNo = allDateList.stream()
                    .map(PcPackOtherDto::getLotNo) // 先提取lotNo
                    .distinct() // 去重
                    .collect(Collectors.joining(",\n")); // 用换行符连接所有字符串

            //c.填充表格数据
            //第一行数据
            List<String> headList = new ArrayList<>();
            headList.addAll(Arrays.asList("名称", "指令单号", "规格", "码段", "合计"));
            for (String s : headlotNoList) {
                headList.add(s);
            }
            dateList.add(headList);
            //后面表格数据
            for (PcPackOtherDto mtlDto : sameConditionList2) {
                List<String> bodyList = new ArrayList<>();
                //前半部分
                bodyList.add(mtlDto.getMtlName() != null ? mtlDto.getMtlName() : "");
                bodyList.add(lotNo);
                bodyList.add(mtlDto.getMtlSpec() != null ? mtlDto.getMtlSpec() : "");

//                String size = mtlDto.getSize1() + "-" + mtlDto.getSize2();
                // 处理 Size1 和 Size2 的逻辑,解决没有值显示null
                String size1 = mtlDto.getSize1();
                String size2 = mtlDto.getSize2();
                String size;
                if (size1 == null || size1.trim().isEmpty()) {
                    size = (size2 == null || size2.trim().isEmpty()) ? "" : size2;
                } else if (size2 == null || size2.trim().isEmpty()) {
                    size = size1;
                } else {
                    size = size1 + "-" + size2;
                }

                bodyList.add(size);
                bodyList.add(String.valueOf(mtlDto.getPurQty()));
                //后半部分数据
                String currentLotNo = null; // 用来跟踪当前正在处理的lotNo
                boolean foundMatch = false; // 标记是否找到了匹配的mtlNo和MtlSpec
                for (PcPackOtherDto dto : sameConditionList) {

                    //在list中有多个lotNo相同，但是mtlNo和MtlSpec不同的数据
                    //list中是按照lotNo排序的，所以相同lotNo在一起出现
                    //现在要做的就是在这部分相同lotNo的多条数据中，有和groupList中mtlNo和MtlSpec相同的数据，找到其中的purQty存到newGroupList中
                    //如果在这部分相同lotNo的多条数据中，没有和groupList的中mtlNo和MtlSpec相同的数据，就会把“”存进newGroupList中

                    if (currentLotNo == null || !currentLotNo.equals(dto.getLotNo())) {
                        // 遇到了新的lotNo
                        if (currentLotNo != null && !foundMatch) {
                            // 对于上一个lotNo，如果没有找到匹配，则添加空字符串
                            bodyList.add("");
                        }
                        currentLotNo = dto.getLotNo();
                        foundMatch = false; // 重置匹配标志
                    }

                    boolean a = Objects.equals(dto.getMtlSpec(), mtlDto.getMtlSpec());
                    boolean b = Objects.equals(dto.getMtlName(), mtlDto.getMtlName());
                    boolean c = Objects.equals(dto.getSize1(), mtlDto.getSize1());
                    boolean d = Objects.equals(dto.getSize2(), mtlDto.getSize2());

                    if (a && b && c && d) {
                        bodyList.add(String.valueOf(dto.getPurQty()));
                        foundMatch = true; // 找到匹配，标记为true
                    }
                }
                // 处理最后一个lotNo的情况
                if (!foundMatch) {
                    bodyList.add(""); // 如果最后一个lotNo没有匹配项，添加空字符串
                }

                dateList.add(bodyList);
            }

            //d.处理其他可以填充的数据
            PcPackOtherDto pcPackOtherDto = allDateList.get(0);
            //厂商名字
            SdVendor vendorDto = backMapper.getVendorNameByNo(allDateList.get(0).getVendorNo(), companyId);
            //公司名字
            PurCompany companyDto = purMapper.findPurCompanyInfo(sysUserTokenDTO.getCompanyId());
            //电话
            PcEmployeeRequest2 employeeRequest = new PcEmployeeRequest2();
            employeeRequest.setDeptNo(UserIdThread.get().getDeptId());
            employeeRequest.setName(UserIdThread.get().getUserName());
            List<PcEmployeeListDto> pcEmployeeList = pcEmployeeMapper.getPcEmployeeList(employeeRequest);
            String phonenumber = null;
            if(ObjectUtils.isNotEmpty(pcEmployeeList) && pcEmployeeList.size()>0){
                PcEmployeeListDto pcEmployeeDto = pcEmployeeList.get(0);
                phonenumber = pcEmployeeDto.getMobileNo();
            }

            int count = 0;
            for (PcPackOtherDto t : allDateList) {
                if (!ObjectUtils.isEmpty(t.getPurQty())) {
                    count = count + t.getPurQty();
                }
            }
            //处理下时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        pcPackOtherDto.setPurDateString(sdf.format(pcPackOtherDto.getPurDate()));
        pcPackOtherDto.setReqDateString(sdf.format(pcPackOtherDto.getReqDate()));

            String userName = sysUserTokenDTO.getUserName();
            //如果是越南那边，包材的订购单落款人和电话取purCompany
            if(companyId.equals("HF")){
                phonenumber = companyDto.getTelPhone();
                userName = companyDto.getContacts();
            }

            /*2.填充数据*/
            map.put("mapList", allDateList);
            map.put("p", pcPackOtherDto);
            map.put("s", sysUserTokenDTO);
            map.put("userName", userName);
            map.put("phonenumber", phonenumber);
            map.put("v", vendorDto);
            map.put("c", companyDto);
            map.put("count", count);
            map.put("aa", "--");

            //字体设置：头
            CellStyleBuild cellStyle = new CellStyleBuild();
            cellStyle.setFontName("微软雅黑");
            cellStyle.setFontSize((short) 11);
            cellStyle.setBold(true);
            // 使用修改后的参数创建CellStyle
            CellStyleBuild cellStyle2 = new CellStyleBuild();
            cellStyle2.setFontName("微软雅黑");
            cellStyle2.setFontSize((short) 10);
            cellStyle.setBold(true);

            //是否开启合并
            //如果查出来的数量只有一行，那么不合并
            Boolean isMerge = false;
            if (dateList.size() > 2) {
                isMerge = true;
            }
            int lastRowNum = 2 + dateList.size() - 1;
            List<MergeBuild> mergeRulesList = new ArrayList<>();
            MergeBuild mergeBuild = new MergeBuild();
            mergeBuild.setStartRow(3);
            mergeBuild.setEndRow(lastRowNum);
            mergeBuild.setStartCol(1);
            mergeBuild.setEndCol(1);
            mergeRulesList.add(mergeBuild);

            //头部
            ArrayList<Integer> headerRowIndexList = new ArrayList<>();
            headerRowIndexList.add(0);

            TemplateExportParams templateParams = new TemplateExportParams("templates/包材订购单-分段纵(请购类型)模板.xls", true);
            templateParams.setColForEach(true);
            ExcelUtils.setResponseZF(response, fileName);
            ExcelPoiUtils.writeExcelList222(response, map, dateList,
                    templateParams,
                    2, 0,18,headerRowIndexList,
                    cellStyle,cellStyle2,isMerge,mergeRulesList);
        } catch (Exception e) {
            log.error("订购单导出失败, 错误信息: {}", e.getMessage());
            throw new ServiceErrorException(e.getMessage());
        }

    }


    /**
     * 导出订购单(分段/横)
     * @param request
     * @param response
     */
    @Override
    public void exportPurchaseOrderByTransverse(NotOrderMaterialRequest request, HttpServletResponse response) {
        try {

            /*1.判断*/
            //判断>>订购单号不能为空
            if(request.getPurNo() == null || request.getPurNo().isEmpty()){
                throw new ServiceErrorException("订购单号不能为空！");
            }
            //文件名
            String fileName = "包材订购单(分段/横)_" + request.getVendorName() + "_" + DateUtils.dateTimeNow() + ".xlsx";

            /*2.查询所有数据*/
            //request : purType + purNo + vendorName
            SysUserTokenDTO sysUserTokenDTO = UserIdThread.get();
            String companyId = sysUserTokenDTO.getCompanyId();
            String userName = sysUserTokenDTO.getUserName();
            NotOrderMaterialRequest r = new NotOrderMaterialRequest();
            r.setPurNo(request.getPurNo());
            String purNo = request.getPurNo();
            //a.查询所有数据
            List<PcPackOtherDto> list = pOtherOrderingOperationMapper.getOrderedDetailsList(companyId,r);
            //a.查该订单号所有规格
            List<String> SpecList = pOtherOrderingOperationMapper.getMtlSpec(companyId, purNo);
            ///判断>>该订购单号没有不同规格的材料！
            if (ObjectUtils.isEmpty(SpecList) || (SpecList.size() == 1 && SpecList.get(0) == null)) {
                throw new ServiceErrorException("该订购单号没有不同规格的材料");
            }
            //判空
            if(ObjectUtils.isEmpty(list)){
                throw new ServiceErrorException("未找到该订购单号的材料数据！");
            }
            /*判断是否是鞋托和鞋盒*/
            PcPackOtherDto dto1 = list.get(0);
            String typeName = dto1.getTypeName();
            Boolean flag = typeName != null && (typeName.equals("鞋托") || typeName.equals("鞋盒"));
            if (!flag) {


                //b.查询：该指令的规格和码段(MTL_SPEC ASC,SIZE1 ASC,SIZE2 ASC)以及相同条件的数量-----现在不看size了
                List<PcPackOtherDto> specAndSizeList = pOtherOrderingOperationMapper.getMtlSpecAndSize(companyId, purNo);
                //c.统计lotNo+mtlName+mtlspec+size1+size2相同的数据的订购数量(MTL_NAME ASC,MTL_SPEC ASC,LOT_NO ASC,SIZE1 ASC,SIZE2 ASC)-----现在不看size了
                List<PcPackOtherDto> sameConditionList = pOtherOrderingOperationMapper.getPurQtyByMtlSpec(companyId, purNo);
                //d.统计lotNo+mtlName对应的总purQTY（lotNo升序,mtlName升序，mtlSPesc升序）
                List<PcPackOtherDto> sameConditionList2 = pOtherOrderingOperationMapper.getPurQtyByLotNo(companyId, purNo);
//        //e.统计mtlspec+size1+size2相同的数据的订购数量（）
//        List<PcPackOtherDto> purQTYList2 = packagOrderingOperationMapper.getAllPurQtyByMtlSpec(companyId, r);

                //判空
                if (ObjectUtils.isEmpty(list) || ObjectUtils.isEmpty(specAndSizeList) || ObjectUtils.isEmpty(sameConditionList) || ObjectUtils.isEmpty(sameConditionList2)) {
                    throw new ServiceErrorException("该订购单号没有数据！");
                }

                /*3.处理数据*/
                /*a.模板其他字段数据*/
                PcPackOtherDto pcPackOtherDto = list.get(0);
                //厂商名字
                SdVendor vendorDto = backMapper.getVendorNameByNo(list.get(0).getVendorNo(), companyId);
                //公司名字
                PurCompany companyDto = purMapper.findPurCompanyInfo(sysUserTokenDTO.getCompanyId());
                //电话
                PcEmployeeRequest2 employeeRequest = new PcEmployeeRequest2();
                employeeRequest.setDeptNo(UserIdThread.get().getDeptId());
                employeeRequest.setName(UserIdThread.get().getUserName());
                List<PcEmployeeListDto> pcEmployeeList = pcEmployeeMapper.getPcEmployeeList(employeeRequest);
                String phonenumber = null;
                if (ObjectUtils.isNotEmpty(pcEmployeeList) && pcEmployeeList.size() > 0) {
                    PcEmployeeListDto pcEmployeeDto = pcEmployeeList.get(0);
                    phonenumber = pcEmployeeDto.getMobileNo();
                }

                //处理下时间格式
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                pcPackOtherDto.setPurDateString(sdf.format(pcPackOtherDto.getPurDate()));
                pcPackOtherDto.setReqDateString(sdf.format(pcPackOtherDto.getReqDate()));
                //总的数量
                int count = 0;

                /*b.中间表格数据*/
                List<List<String>> dateList = new ArrayList<>();
                //合计的数量
                List<String> countList = new ArrayList<>();
                //前两行数据
                List<String> headList1 = new ArrayList<>();
                List<String> headList2 = new ArrayList<>();
                headList1.addAll(Arrays.asList("指令单号", "码段"));
                headList2.addAll(Arrays.asList("指令单号", "规格"));
                for (PcPackOtherDto specAndSize : specAndSizeList) {
//                String s = formatSize(specAndSize.getSize1(), specAndSize.getSize2());
                    // 处理 Size1 和 Size2 的逻辑,解决没有值显示null
                    String size1 = specAndSize.getSize1();
                    String size2 = specAndSize.getSize2();
                    String s;
                    if (size1 == null || size1.trim().isEmpty()) {
                        s = (size2 == null || size2.trim().isEmpty()) ? "" : size2;
                    } else if (size2 == null || size2.trim().isEmpty()) {
                        s = size1;
                    } else {
                        s = size1 + "-" + size2;
                    }

                    headList1.add(s);
                    headList2.add(specAndSize.getMtlSpec());
                    countList.add(String.valueOf(specAndSize.getPurQty()));
                    count += specAndSize.getPurQty();
                }


                //截断在固定列加上别的
                // 在第15和第16列之间插入purQty和“备注”
                insertValuesAndShift(headList1, 14, new String[]{"合计", "备注"});
                insertValuesAndShift(headList2, 14, new String[]{"", ""});
                insertValuesAndShift(countList, 12, new String[]{String.valueOf(count), ""});
                dateList.addAll(Arrays.asList(headList1, headList2));

                //后面的数据
                for (PcPackOtherDto mtlDto : sameConditionList2) {
                    List<String> bodyList = new ArrayList<>();
                    //a.前半部分
                    bodyList.add(mtlDto.getLotNo() != null ? mtlDto.getLotNo() : "");
                    bodyList.add(mtlDto.getMtlName() != null ? mtlDto.getMtlName() : "");

                    //b.后半部分数据
                    String current = null;
                    boolean foundMatch = false; // 标记是否找到了匹配的
                    for (PcPackOtherDto dto : sameConditionList) {
//                    String fix = dto.getMtlSpec() + dto.getSize1() + dto.getSize2();
                        String fix = dto.getMtlSpec();
                        if (current == null || !current.equals(fix)) {
                            // 遇到了新的lotNo
                            if (current != null && !foundMatch) {
                                // 对于上一个lotNo，如果没有找到匹配，则添加空字符串
                                bodyList.add("");
                            }
//                        current = dto.getMtlSpec() + dto.getSize1() + dto.getSize2();
                            current = dto.getMtlSpec();
                            foundMatch = false; // 重置匹配标志
                        }
                        // 检查当前dto的LotNo和MtlName是否与mtlDto的对应值相等
                        Boolean c = Objects.equals(dto.getLotNo(), mtlDto.getLotNo()) && Objects.equals(dto.getMtlName(), mtlDto.getMtlName());
                        if (c) {
                            // 找到了匹配项，添加数量
                            bodyList.add(String.valueOf(dto.getPurQty()));
                            foundMatch = true;
                        }

                    }

                    // 如果没有找到匹配，则添加空字符串
                    if (!foundMatch) {
                        bodyList.add("");
                    }

                    // 确保bodyList的大小至少为14
                    while (bodyList.size() < 14) {
                        bodyList.add("");
                    }

                    // 在第15和第16列之间插入purQty和“备注”
                    // 将第15列及以后的数据向后移动两位
                    List<String> tempList = new ArrayList<>(bodyList.subList(14, bodyList.size()));
                    bodyList.subList(14, bodyList.size()).clear();
                    bodyList.add(14, String.valueOf(mtlDto.getPurQty())); // 第15列
                    bodyList.add(15, mtlDto.getPurRemark()); // 第16列
                    bodyList.addAll(16, tempList); // 从第17列开始继续添加数据

                    dateList.add(bodyList);
                }

                //如果是越南那边，包材的订购单落款人和电话取purCompany
                if(companyId.equals("HF")){
                    phonenumber = companyDto.getTelPhone();
                    userName = companyDto.getContacts();
                }

                /*4.map填充数据*/
                //s,p,c,v
                HashMap<String, Object> map = new HashMap<>();
                map.put("s", sysUserTokenDTO);
                map.put("p", pcPackOtherDto);
                map.put("v", vendorDto);
                map.put("c", companyDto);
                map.put("list2", countList);
                map.put("userName", userName);
                map.put("phonenumber", phonenumber);
                map.put("aa", "--");

                /*5.文件设置*/
                //自定义样式
                CellStyleBuild cellStyle = new CellStyleBuild();
                cellStyle.setFontName("微软雅黑");
                cellStyle.setFontSize((short) 11);
                cellStyle.setBold(true);

                CellStyleBuild cellStyle2 = new CellStyleBuild();
                cellStyle2.setFontName("微软雅黑");
                cellStyle2.setFontSize((short) 11);

                ArrayList<Integer> headerRowIndexList = new ArrayList<>();
                headerRowIndexList.addAll(Arrays.asList(0, 1));

                TemplateExportParams templateParams = new TemplateExportParams("templates/包材订购单-分段横(请购类型)模板.xls", true);
                templateParams.setColForEach(true);
                ExcelUtils.setResponseZF(response, fileName);
                ExcelPoiUtils.writeExcelList222(response, map, dateList,
                        templateParams,
                        2, 0, 17, headerRowIndexList,
                        cellStyle, cellStyle2, false, null);
            }else{

                //b.查询：该指令的规格和码段(MTL_NAME ASC,MTL_SPEC ASC,SIZE1 ASC,SIZE2 ASC)以及相同条件的数量-----现在不看size了
                List<PcPackOtherDto> specAndSizeList = pOtherOrderingOperationMapper.getMtlSpecAndSize2(companyId, purNo);
                //c.统计lotNo+mtlName+mtlspec+size1+size2相同的数据的订购数量(MTL_NAME ASC,MTL_SPEC ASC,LOT_NO ASC,SIZE1 ASC,SIZE2 ASC)-----现在不看size了
                List<PcPackOtherDto> sameConditionList = pOtherOrderingOperationMapper.getPurQtyByMtlSpec2(companyId, purNo);
                //d.统计lotNo+mtlName对应的总purQTY（lotNo升序,mtlName升序，mtlSPesc升序）
                List<PcPackOtherDto> sameConditionList2 = pOtherOrderingOperationMapper.getPurQtyByLotNo2(companyId, purNo);
//        //e.统计mtlspec+size1+size2相同的数据的订购数量（）
//        List<PcPackOtherDto> purQTYList2 = packagOrderingOperationMapper.getAllPurQtyByMtlSpec(companyId, r);

                //判空
                if (ObjectUtils.isEmpty(list) || ObjectUtils.isEmpty(specAndSizeList) || ObjectUtils.isEmpty(sameConditionList) || ObjectUtils.isEmpty(sameConditionList2)) {
                    throw new ServiceErrorException("该订购单号没有数据！");
                }

                /*3.处理数据*/
                /*a.模板其他字段数据*/
                PcPackOtherDto pcPackOtherDto = list.get(0);
                //厂商名字
                SdVendor vendorDto = backMapper.getVendorNameByNo(list.get(0).getVendorNo(), companyId);
                //公司名字
                PurCompany companyDto = purMapper.findPurCompanyInfo(sysUserTokenDTO.getCompanyId());
                //电话
                PcEmployeeRequest2 employeeRequest = new PcEmployeeRequest2();
                employeeRequest.setDeptNo(UserIdThread.get().getDeptId());
                employeeRequest.setName(UserIdThread.get().getUserName());
                List<PcEmployeeListDto> pcEmployeeList = pcEmployeeMapper.getPcEmployeeList(employeeRequest);
                String phonenumber = null;
                if (ObjectUtils.isNotEmpty(pcEmployeeList) && pcEmployeeList.size() > 0) {
                    PcEmployeeListDto pcEmployeeDto = pcEmployeeList.get(0);
                    phonenumber = pcEmployeeDto.getMobileNo();
                }

                //处理下时间格式
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                pcPackOtherDto.setPurDateString(sdf.format(pcPackOtherDto.getPurDate()));
                pcPackOtherDto.setReqDateString(sdf.format(pcPackOtherDto.getReqDate()));
                //总的数量
                int count = 0;

                /*b.中间表格数据*/
                List<List<String>> dateList = new ArrayList<>();
                //合计的数量
                List<String> countList = new ArrayList<>();
                //前两行数据
                List<String> headList1 = new ArrayList<>();
                List<String> headList2 = new ArrayList<>();
                List<String> headList3 = new ArrayList<>();
                headList1.addAll(Arrays.asList("指令单号", "订单码段"));
                //headList3.addAll(Arrays.asList("指令单号", "鞋盒编号"));
                //headList2.addAll(Arrays.asList("指令单号", "鞋盒规格"));
                //判断是鞋托还是鞋盒
                if(typeName.equals("鞋盒")){
                    headList3.addAll(Arrays.asList("指令单号", "鞋盒编号"));
                    headList2.addAll(Arrays.asList("指令单号", "鞋盒规格"));
                }else{
                    headList3.addAll(Arrays.asList("指令单号", "鞋托编号"));
                    headList2.addAll(Arrays.asList("指令单号", "鞋托规格"));
                }

                for (PcPackOtherDto specAndSize : specAndSizeList) {
//                String s = formatSize(specAndSize.getSize1(), specAndSize.getSize2());
                    // 处理 Size1 和 Size2 的逻辑,解决没有值显示null
                    String size1 = specAndSize.getSize1();
                    String size2 = specAndSize.getSize2();
                    String s;
                    if (size1 == null || size1.trim().isEmpty()) {
                        s = (size2 == null || size2.trim().isEmpty()) ? "" : size2;
                    } else if (size2 == null || size2.trim().isEmpty()) {
                        s = size1;
                    } else {
                        s = size1 + "-" + size2;
                    }

                    headList1.add(s);
                    headList3.add(specAndSize.getMtlName());
                    headList2.add(specAndSize.getMtlSpec());
                    countList.add(String.valueOf(specAndSize.getPurQty()));
                    count += specAndSize.getPurQty();
                }


                //截断在固定列加上别的
                // 在第15和第16列之间插入purQty和“备注”
                insertValuesAndShift(headList1, 14, new String[]{"合计", "备注"});
                insertValuesAndShift(headList2, 14, new String[]{"", ""});
                insertValuesAndShift(headList3, 14, new String[]{"", ""});
                insertValuesAndShift(countList, 12, new String[]{String.valueOf(count), ""});
                dateList.addAll(Arrays.asList(headList1,headList3, headList2));

                //后面的数据
                for (PcPackOtherDto mtlDto : sameConditionList2) {
                    List<String> bodyList = new ArrayList<>();
                    //a.前半部分
                    bodyList.add(mtlDto.getLotNo() != null ? mtlDto.getLotNo() : "");
                    bodyList.add("数量");

                    //b.后半部分数据
                    String current = null;
                    boolean foundMatch = false; // 标记是否找到了匹配的
                    for (PcPackOtherDto dto : sameConditionList) {
//                    String fix = dto.getMtlSpec() + dto.getSize1() + dto.getSize2();
                        String fix = dto.getMtlSpec() + dto.getMtlName();
                        if (current == null || !current.equals(fix)) {
                            // 遇到了新的lotNo
                            if (current != null && !foundMatch) {
                                // 对于上一个lotNo，如果没有找到匹配，则添加空字符串
                                bodyList.add("");
                            }
//                        current = dto.getMtlSpec() + dto.getSize1() + dto.getSize2();
                            current = dto.getMtlSpec()  + dto.getMtlName();
                            foundMatch = false; // 重置匹配标志
                        }
                        // 检查当前dto的LotNo和MtlName是否与mtlDto的对应值相等
                        //Boolean c = Objects.equals(dto.getLotNo(), mtlDto.getLotNo()) && Objects.equals(dto.getMtlName(), mtlDto.getMtlName());
                        Boolean c = dto.getLotNo().equals(mtlDto.getLotNo());
                        if (c) {
                            // 找到了匹配项，添加数量
                            bodyList.add(String.valueOf(dto.getPurQty()));
                            foundMatch = true;
                        }

                    }

                    // 如果没有找到匹配，则添加空字符串
                    if (!foundMatch) {
                        bodyList.add("");
                    }

                    // 确保bodyList的大小至少为14
                    while (bodyList.size() < 14) {
                        bodyList.add("");
                    }

                    // 在第15和第16列之间插入purQty和“备注”
                    // 将第15列及以后的数据向后移动两位
                    List<String> tempList = new ArrayList<>(bodyList.subList(14, bodyList.size()));
                    bodyList.subList(14, bodyList.size()).clear();
                    bodyList.add(14, String.valueOf(mtlDto.getPurQty())); // 第15列
                    bodyList.add(15, mtlDto.getPurRemark()); // 第16列
                    bodyList.addAll(16, tempList); // 从第17列开始继续添加数据

                    dateList.add(bodyList);
                }

                //如果是越南那边，包材的订购单落款人和电话取purCompany
                if(companyId.equals("HF")){
                    phonenumber = companyDto.getTelPhone();
                    userName = companyDto.getContacts();
                }

                /*4.map填充数据*/
                //s,p,c,v
                HashMap<String, Object> map = new HashMap<>();
                map.put("s", sysUserTokenDTO);
                map.put("p", pcPackOtherDto);
                map.put("v", vendorDto);
                map.put("c", companyDto);
                map.put("list2", countList);
                map.put("userName", userName);
                map.put("phonenumber", phonenumber);
                map.put("aa", "--");

                /*5.文件设置*/
                //自定义样式
                CellStyleBuild cellStyle = new CellStyleBuild();
                cellStyle.setFontName("微软雅黑");
                cellStyle.setFontSize((short) 11);
                cellStyle.setBold(true);

                CellStyleBuild cellStyle2 = new CellStyleBuild();
                cellStyle2.setFontName("微软雅黑");
                cellStyle2.setFontSize((short) 11);

                ArrayList<Integer> headerRowIndexList = new ArrayList<>();
                headerRowIndexList.addAll(Arrays.asList(0, 1,2));

                TemplateExportParams templateParams = new TemplateExportParams("templates/包材订购单-分段横(请购类型)模板-鞋托鞋盒.xls", true);
                templateParams.setColForEach(true);
                ExcelUtils.setResponseZF(response, fileName);
                ExcelPoiUtils.writeExcelList222(response, map, dateList,
                        templateParams,
                        2, 0, 17, headerRowIndexList,
                        cellStyle, cellStyle2, false, null);
            }
        } catch (Exception e) {
            log.error("包材订购单导出失败, 错误信息: {}", e.getMessage());
            throw new ServiceErrorException(e.getMessage());
        }
    }

//    /**
//     * 导出订购单(分段/纵)
//     * @param request
//     * @param response
//     */
//    @Override
//    public void exportPurchaseOrderByLongitudinal(NotOrderMaterialRequest request, HttpServletResponse response) {
//        try {
//
//        if(request.getPurNo() == null || request.getPurNo().isEmpty()){
//            throw new ServiceErrorException("订购单号不能为空！");
//        }
//        String fileName = "包材订购单(分段/纵)_" + request.getVendorName() + "-" + DateUtils.dateTimeNow() + ".xlsx";
//        //request : purType + purNo + vendorName
//        HashMap<String, Object> map = new HashMap<>();
//        SysUserTokenDTO sysUserTokenDTO = UserIdThread.get();
//        NotOrderMaterialRequest r = new NotOrderMaterialRequest();
//        r.setPurNo(request.getPurNo());
//        List<PcPackOtherDto> list = pOtherOrderingOperationMapper.getOrderedDetailsList(sysUserTokenDTO.getCompanyId(), r);
//
//        // 如果确实需要List<String>类型的lotNoList，可以在转换前先收集到List，再转换为单个字符串
//        List<String> lotNoList = list.stream()
//                .map(dto -> dto.getLotNo().substring(dto.getLotNo().indexOf("-") + 1))
//                .distinct()
//                .collect(Collectors.toList());
//
//        // 整合操作，提取、处理、去重并用换行符连接
//        String lotNo = list.stream()
//                .map(PcPackOtherDto::getLotNo) // 先提取lotNo
//                .distinct() // 去重
//                .collect(Collectors.joining(",\n")); // 用换行符连接所有字符串
//
//
//        //相同条件的统计purQty
//        List<PcPackOtherDto> result = list.stream()
//                .collect(Collectors.groupingBy(dto -> dto.getLotNo() + dto.getMtlNo() + dto.getMtlUnit() + dto.getSize1() + dto.getSize2(),
//                        Collectors.reducing((dto1, dto2) -> {
//                            dto1.setPurQty(dto1.getPurQty() + dto2.getPurQty());
//                            return dto1;
//                        })))
//                .values()
//                .stream()
//                .map(Optional::get)
//                .collect(Collectors.toList());
//        int count1 = 0;
//        for (PcPackOtherDto t : result) {
//            if (!ObjectUtils.isEmpty(t.getPurQty())) {
//                count1 = count1 + t.getPurQty();
//            }
//        }
//        PcPackOtherDto pcPackOtherDto = list.get(0);
//        //厂商名字
//        SdVendor vendorDto = backMapper.getVendorNameByNo(list.get(0).getVendorNo(), sysUserTokenDTO.getCompanyId());
//        //公司名字
//        SdCompany companyDto = sdCompanyMapper.findAllBYCompanyId(sysUserTokenDTO.getCompanyId());
//        int count = 0;
//        for (PcPackOtherDto t : list) {
//            if (!ObjectUtils.isEmpty(t.getPurQty())) {
//                count = count + t.getPurQty();
//            }
//        }
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        pcPackOtherDto.setPurDateString(sdf.format(pcPackOtherDto.getPurDate()));
//        pcPackOtherDto.setReqDateString(sdf.format(pcPackOtherDto.getReqDate()));
//        map.put("s", sysUserTokenDTO);
//        map.put("mapList", list);
//        map.put("p", pcPackOtherDto);
//        map.put("v", vendorDto);
//        map.put("c", companyDto);
//        map.put("count", count);
//        //获取模板
//        TemplateExportParams templateExportParams = new TemplateExportParams("excel/dcmb.xls");
//        //开启横向遍历 开启横向遍历 开启横向遍历
//        templateExportParams.setColForEach(true);
//        map.put("lotNoList", lotNoList);
//        map.put("result", result);
//        map.put("count1", count1);
//
//        //new ArrayList<>();
//        List<String> headList = new ArrayList<>();
//        headList.addAll(Arrays.asList("名称", "指令单号", "规格", "码段", "合计"));
//        for (String s : lotNoList) {
//            headList.add(s);
//        }
//        List<PcPackOtherDto> groupList = pOtherOrderingOperationMapper.getOrderedDetailsGroupList(sysUserTokenDTO.getCompanyId(), r);
//        List<List<String>> newGroupList2 = new ArrayList<>();
//        newGroupList2.add(headList);
//        for (PcPackOtherDto g : groupList) {
//            String size = g.getSize1() + "-" + g.getSize2();
//            List<String> newGroupList = new ArrayList<>();
//            newGroupList.add(g.getMtlName());
//            newGroupList.add(lotNo);
//            newGroupList.add(g.getMtlSpec() != null ? g.getMtlSpec() : "");
//            newGroupList.add(size != null ? size : "");
//            newGroupList.add(String.valueOf(g.getPurQty()) != null ? String.valueOf(g.getPurQty()) : "");
//
//            String currentLotNo = null; // 用来跟踪当前正在处理的lotNo
//            boolean foundMatch = false; // 标记是否找到了匹配的mtlNo和MtlSpec
//            for (PcPackOtherDto dto : list) {
//
//                //在list中有多个lotNo相同，但是mtlNo和MtlSpec不同的数据
//                //list中是按照lotNo排序的，所以相同lotNo在一起出现
//                //现在要做的就是在这部分相同lotNo的多条数据中，有和groupList中mtlNo和MtlSpec相同的数据，找到其中的purQty存到newGroupList中
//                //如果在这部分相同lotNo的多条数据中，没有和groupList的中mtlNo和MtlSpec相同的数据，就会把“”存进newGroupList中
//
//                if (currentLotNo == null || !currentLotNo.equals(dto.getLotNo())) {
//                    // 遇到了新的lotNo
//                    if (currentLotNo != null && !foundMatch) {
//                        // 对于上一个lotNo，如果没有找到匹配，则添加空字符串
//                        newGroupList.add("");
//                    }
//                    currentLotNo = dto.getLotNo();
//                    foundMatch = false; // 重置匹配标志
//                }
//
//                boolean specEquals = Objects.equals(dto.getMtlSpec(), g.getMtlSpec());
//                boolean noEquals = Objects.equals(dto.getMtlNo(), g.getMtlNo());
//
//                if (specEquals && noEquals) {
//                    newGroupList.add(String.valueOf(dto.getPurQty()));
//                    foundMatch = true; // 找到匹配，标记为true
//                }
//            }
//            // 处理最后一个lotNo的情况
//            if (!foundMatch) {
//                newGroupList.add(""); // 如果最后一个lotNo没有匹配项，添加空字符串
//            }
//
//            newGroupList2.add(newGroupList);
//            }
//
//        CellStyleBuild cellStyle = new CellStyleBuild();
//        cellStyle.setFontName("微软雅黑");
//        cellStyle.setFontSize((short) 11);
//        cellStyle.setBold(true);
//        // 使用修改后的参数创建CellStyle
//
//        CellStyleBuild cellStyle2 = new CellStyleBuild();
//        cellStyle2.setFontName("微软雅黑");
//        cellStyle2.setFontSize((short) 10);
//        cellStyle.setBold(true);
//
//        //是否开启合并
//        //如果查出来的数量只有一行，那么不合并
//        Boolean isMerge = false;
//        if (newGroupList2.size() > 2) {
//            isMerge = true;
//        }
//        int lastRowNum = 2 + newGroupList2.size() - 1;
//        List<MergeBuild> mergeRulesList = new ArrayList<>();
//        MergeBuild mergeBuild = new MergeBuild();
//        mergeBuild.setStartRow(3);
//        mergeBuild.setEndRow(lastRowNum);
//        mergeBuild.setStartCol(1);
//        mergeBuild.setEndCol(1);
//        mergeRulesList.add(mergeBuild);
//
//        ArrayList<Integer> headerRowIndexList = new ArrayList<>();
//        headerRowIndexList.add(0);
//
//
//                ExcelUtils.setResponseZF(response, fileName);
//                ExcelPoiUtils.writeExcelList2(response, map, newGroupList2,
//                        "templates/包材订购单-分段纵(请购类型)模板.xls", fileName,
//                        2, 0,18,headerRowIndexList,
//                        cellStyle,cellStyle2,isMerge,mergeRulesList);
//            } catch (Exception e) {
//                log.error("包材订购单导出失败, 错误信息: {}", e.getMessage());
//            throw new ServiceErrorException(e.getMessage());
//            }
//
//        }
//
//    /**
//     * 导出订购单(分段/横)
//     * @param request
//     * @param response
//     */
//    @Override
//    public void exportPurchaseOrderByTransverse(NotOrderMaterialRequest request, HttpServletResponse response) {
//        try {
//
//        //判断>>订购单号不能为空
//        if(request.getPurNo() == null || request.getPurNo().isEmpty()){
//            throw new ServiceErrorException("订购单号不能为空！");
//        }
//        //文件名
//        String fileName = "包材订购单(分段/横)_" + request.getVendorName() + "-" + DateUtils.dateTimeNow() + ".xlsx";
//
//        /*查询所有数据*/
//        //request : purType + purNo + vendorName
//        SysUserTokenDTO sysUserTokenDTO = UserIdThread.get();
//        NotOrderMaterialRequest r = new NotOrderMaterialRequest();
//        r.setPurNo(request.getPurNo());
//        List<PcPackOtherDto> list = pOtherOrderingOperationMapper.getOrderedDetailsList(sysUserTokenDTO.getCompanyId(),r);
//        //查该订单号所有规格
//        List<PcPackOtherDto> SpecList = pOtherOrderingOperationMapper.getMtlSpecAndSize(sysUserTokenDTO.getCompanyId(), r);
//
//            //每个lotNo对应相应的总purQTY
//        List<PcPackOtherDto> CountPurQTYList = pOtherOrderingOperationMapper.getPurQtyByLotNo(sysUserTokenDTO.getCompanyId(), r);
//        //lotNo对应不同的MTLSPec的不同purQTY
//        List<PcPackOtherDto> purQTYList = pOtherOrderingOperationMapper.getPurQtyByMtlSpec(sysUserTokenDTO.getCompanyId(), r);
//        //不同mtlNo的所有数量
//        List<PcPackOtherDto> purQTYList2 = pOtherOrderingOperationMapper.getAllPurQtyByMtlSpec(sysUserTokenDTO.getCompanyId(), r);
//        ///判断>>该订购单号没有不同规格的材料！
//        List<PcPackOtherDto> specList = SpecList.stream().filter(Objects::nonNull).filter(a -> StringUtils.isNotBlank(a.getMtlSpec())).collect(Collectors.toList());
//
//        if(ArrayUtils.isEmpyt(specList)){
//            throw new ServiceErrorException("该订购单号没有不同规格的材料");
//        }
//
//
//        /*处理数据*/
//        /*模板其他字段数据*/
//        PcPackOtherDto pcPackOtherDto = list.get(0);
//        //厂商名字
//        SdVendor vendorDto = backMapper.getVendorNameByNo(list.get(0).getVendorNo(), sysUserTokenDTO.getCompanyId());
//        //公司名字
//        SdCompany companyDto = sdCompanyMapper.findAllBYCompanyId(sysUserTokenDTO.getCompanyId());
//
//        /*自定义模板数据*/
//        //头
//        List<List<String>> dateList = new ArrayList<>();
//        List<String> headList1 = new ArrayList<>();
//        List<String> headList2 = new ArrayList<>();
//        headList1.addAll(Arrays.asList("指令单号", "规格", "备注", "合计"));
//        headList2.addAll(Arrays.asList("指令单号", "码段", "备注", "合计"));
//        for (int i = 0; i < specList.size(); i++) {
//            headList1.add(specList.get(i).getMtlSpec());
//            float size1 = specList.get(i).getSize1();
//            float size2 = specList.get(i).getSize2();
//            String s = formatSize(size1, size2);
//            headList2.add(s);
//        }
//        while (headList1.size() < 10) {
//            headList1.add("");
//            headList2.add("");
//        }
//        dateList.addAll(Arrays.asList(headList2, headList1));
//        //尾部数据
//        for (PcPackOtherDto countPurQty : CountPurQTYList) {
//            List<String> bodyList = new ArrayList<>();
//            bodyList.add(countPurQty.getLotNo());
//            bodyList.add(countPurQty.getMtlName());
//            bodyList.add(countPurQty.getPurRemark());
//            bodyList.add(String.valueOf(countPurQty.getPurQty()));
//            boolean foundMatch = false; // 标记是否找到匹配项
//            for (PcPackOtherDto specDto : specList) {
//                for (PcPackOtherDto purQtyDto : purQTYList) {
//                    if (purQtyDto.getLotNo().equals(countPurQty.getLotNo())
//                            && purQtyDto.getMtlSpec().equals(specDto.getMtlSpec())
//                            && purQtyDto.getSize1() == specDto.getSize1()
//                            && purQtyDto.getSize2() == specDto.getSize2()) {
//                        bodyList.add(String.valueOf(purQtyDto.getPurQty()));
//                        foundMatch = true; // 找到匹配项
//                        break; // 跳出内层循环，继续遍历下一个specDto
//                    }
//                }
//
//                if (!foundMatch) {
//                    bodyList.add(""); // 当前specDto未找到匹配，添加空字符串
//                }
//                foundMatch = false; // 重置标记，为下一个specDto做准备
//            }
//            dateList.add(bodyList);
//        }
//        ArrayList<String> lastList = new ArrayList<>();
//        int totalCount = 0;
//        for (PcPackOtherDto count : CountPurQTYList) {
//            totalCount += count.getPurQty();
//        }
//        String tCount = String.valueOf(totalCount);
//        lastList.addAll(Arrays.asList("","","合计",tCount));
//        for (PcPackOtherDto p : purQTYList2) {
//            String mCount = String.valueOf(p.getPurQty());
//            lastList.add(mCount);
//        }
//        while (lastList.size() < 10) {
//            lastList.add("");
//        }
//        dateList.add(lastList);
//
//        /*格式化需要字段，填充好数据*/
//        //获取模板
//        TemplateExportParams templateExportParams = new TemplateExportParams("excel/dcmb.xls");
//        //开启横向遍历 开启横向遍历 开启横向遍历
//        templateExportParams.setColForEach(true);
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//        pcPackOtherDto.setPurDateString(sdf.format(pcPackOtherDto.getPurDate()));
//        pcPackOtherDto.setReqDateString(sdf.format(pcPackOtherDto.getReqDate()));
//        //s,p,c,v
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("s", sysUserTokenDTO);
//        map.put("p", pcPackOtherDto);
//        map.put("v", vendorDto);
//        map.put("c", companyDto);
//
//        /*文件*/
//        //自定义样式
//        CellStyleBuild cellStyle = new CellStyleBuild();
//        cellStyle.setFontName("微软雅黑");
//        cellStyle.setFontSize((short) 11);
//        cellStyle.setBold(true);
//
//        CellStyleBuild cellStyle2 = new CellStyleBuild();
//        cellStyle2.setFontName("微软雅黑");
//        cellStyle2.setFontSize((short) 11);
//
//        ArrayList<Integer> headerRowIndexList = new ArrayList<>();
//        headerRowIndexList.addAll(Arrays.asList(0,1,dateList.size()-1));
//
//
//            ExcelUtils.setResponseZF(response, fileName);
//            ExcelPoiUtils.writeExcelList2(response, map, dateList,
//                    "templates/包材订购单-分段横(请购类型)模板.xls", fileName,
//                    2, 0,10,headerRowIndexList,
//                    cellStyle,cellStyle2,false,null);
//        } catch (Exception e) {
//            log.error("包材订购单导出失败, 错误信息: {}", e.getMessage());
//            throw new ServiceErrorException(e.getMessage());
//        }
//    }

    /**
     * 待订购明细:删除
     * @param ids
     * @return
     */
    @Override
    public ResponseInfo deleteNotOrderMaterial(List<Integer> ids) {
        int count = pOtherOrderingOperationMapper.deleteNotOrderMaterial(ids);
        if (count > 0) {
            return ResponseInfo.ok("删除成功");
        }else{
            throw new ServiceErrorException("删除失败");
        }
    }

    private String formatSize(float size1, float size2) {
        return (size1 == 0.0f ? "" : String.valueOf(size1))
                + (size1 != 0.0f && size2 != 0.0f ? "-" : "")
                + (size2 == 0.0f ? "" : String.valueOf(size2));
    }

    /**
     * 在指定位置插入新元素，并将原有数据向后移动。
     * @param list         要处理的列表
     * @param insertIndex  插入元素的起始索引（例如，要插入在第15列，则该值为14）
     * @param values       要插入的值数组
     */
    public static void insertValuesAndShift(List<String> list, int insertIndex, String[] values) {
        // 确保插入索引不会超出范围
        while (list.size() < insertIndex) {
            // 如果插入索引超过当前列表长度，则添加空字符串直到达到插入索引
            list.add("");
        }

        // 创建一个临时列表来保存插入索引及以后的数据
        List<String> tempList = new ArrayList<>(list.subList(insertIndex, list.size()));

        // 清空插入索引及以后的数据
        list.subList(insertIndex, list.size()).clear();

        // 插入指定的值
        for (String value : values) {
            list.add(insertIndex++, value);
        }

        // 从插入索引开始继续添加临时列表中的数据
        list.addAll(insertIndex, tempList);
    }

    /**
     * 获得时间戳+自增数据
     * @param key  根据key获得自增数据
     * @param length 自增长度
     * @param timezone 想要获得的时间戳保留字段 yyMM yyyy-MM-dd HH:mm:ss
     */
    private String generatePrefix(String key,String length,String timezone) {
        //根据key获得自增数据
        RedisAtomicInteger ato = new RedisAtomicInteger(key, redisService.getConnectionFactory());
        String l = "%0" + length + "d"; //%07d
        String value = String.format(l, ato.getAndIncrement());
        redisService.setOutTime(key);
        //时间戳
        LocalDateTime now = LocalDateTime.now();
        String time = now.format(DateTimeFormatter.ofPattern(timezone));
        return time + value;
    }
}
